package com.winexpress.session.order;

import com.winexpress.entity.Customer;
import com.winexpress.entity.OrderHistory;
import com.winexpress.entity.OrderLine;
import com.winexpress.entity.Sales;
import com.winexpress.entity.User;
import com.winexpress.entity.Wine;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javax.ejb.Stateless;
import javax.ejb.LocalBean;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

@Stateless
@LocalBean
public class OrderSessionBean {

    @PersistenceContext
    private EntityManager em;

//  public OrderHistory createOrder(Long userID, String items) {
    public OrderHistory createOrder(OrderMessage inMessage) {
        long userID = inMessage.getUserID();
        String items = inMessage.getItems();

        String[] array = items.split("\\;");

        List<Long> productIDs = new ArrayList<Long>();
        List<Integer> amounts = new ArrayList<Integer>();

        for (int i = 0; i < array.length; i = i + 2) {
            productIDs.add(Long.parseLong(array[i]));
            amounts.add(Integer.parseInt(array[i + 1]));
        }

        Customer user = em.find(Customer.class, userID);
        OrderHistory oh = new OrderHistory();
        oh.setCustomer(user);
        List<OrderLine> ols = new ArrayList<OrderLine>();

        int itemNumber = productIDs.size();

        if (itemNumber == 0) {
            return null;
        }

        for (int i = 0; i < itemNumber; i++) {
            OrderLine ol = new OrderLine();

            Wine wine = em.find(Wine.class, productIDs.get(i));
            ol.setWine(wine);
            ol.setPrice(wine.getPrice());
            ol.setDiscount(wine.getDiscount());
            ol.setCost(wine.getCost());

            int quantity = amounts.get(i);
            ol.setQuantity(quantity);

            ols.add(ol);
        }

        oh.setOrderLines(ols);
        oh.setOrderDiscount(0.0);

        return oh;
    }

    public List<OrderHistory> viewOrders(Long userID) throws Exception {
        Customer user = em.find(Customer.class, userID);
        String strQuery = "SELECT o FROM OrderHistory o WHERE o.customer =:inCustomer";
        Query query = em.createQuery(strQuery);
        query.setParameter("inCustomer", user);
        return query.getResultList();
    }

    public OrderHistory completeOrder(OrderHistory oh) {

        List<OrderLine> order = oh.getOrderLines();
        List<OrderLine> zeroOder = new ArrayList<>();
        for (Object o : order) {
            OrderLine ol = (OrderLine) o;
            Wine w = ol.getWine();
            int stock = w.getStock();

            if (stock >= ol.getQuantity()) {
                stock = stock - ol.getQuantity();
                w.setStock(stock);
                if (!(w.getStock() > 0)) {
                    w.setIsActive(false);
                }

                this.addSales(w, ol.getQuantity());

                em.merge(w);
                em.persist(ol);
            } else {
                ol.setQuantity(0);
                em.persist(ol);
            }
        }
        
        

        if (order.isEmpty()) {
            return null;
        }

        em.persist(oh);
        em.flush();
        return oh;
    }

    public boolean addSales(Wine w, int quantity) {
        Sales sales = this.getSales(w);

        int oldQuantity = sales.getQuantity();
        int newQuantity = oldQuantity + quantity;
        sales.setQuantity(newQuantity);

        em.persist(sales);
        em.flush();

        return true;
    }

    private Sales getSales(Wine w) {
        Wine wine = em.find(Wine.class, w.getId());
        String strQuery = "SELECT s FROM Sales s WHERE s.wine =:inWine AND s.year=:inYear AND s.month=:inMonth";
        Query query = em.createQuery(strQuery);
        query.setParameter("inWine", wine);
        int year = Calendar.getInstance().get(Calendar.YEAR);
        query.setParameter("inYear", year);
        int month = Calendar.getInstance().get(Calendar.MONTH);
        query.setParameter("inMonth", month);

        Sales sales = (Sales) query.getSingleResult();
        if (sales == null) {
            Sales newSales = new Sales();
            newSales.setWine(wine);
            newSales.setYear(year);
            newSales.setMonth(month);
            newSales.setQuantity(0);
            em.persist(newSales);
            em.flush();
            return newSales;
        }

        return sales;
    }
}
